package com.ymx.darling.bean.entity;

import com.ymx.darling.executor.mapping.relation.RelationFieldInfo;
import com.ymx.darling.bean.entity.listener.SetListener;
import com.ymx.darling.util.StringUtil;

import java.util.List;
import java.util.Map;

/**
 * 保存一个javaBean的基本信息
 * @author 爱Java的小于
 */
public class BeanInfoContent implements BeanInfo {
    /**
     * 结果集的映射类型
     */
    private Class<?> module;

    /**
     * 实体类对应的数据库表名
     */
    private String tableName;

    /**
     * 数据库表对应的schema
     */
    private String schemaName;

    /**
     * 数据库字段名称与属性的映射
     */
    private Map<String, FieldInfo> simpleColumnMap;

    /**
     * 字段名称为key 字段为value的所有field集合
     */
    private Map<String, FieldInfo> fieldMap;

    /**
     * 关联类型字段信息列表
     */
    private List<RelationFieldInfo> relationFieldInfoList;

    /**
     * 可以执行查询操作的字段
     */
    private FieldInfo[] queryColumns;

    /**
     * 可以执行更新操作的字段
     */
    private FieldInfo[] updateColumns;

    /**
     * 指明id字段名称
     */
    private FieldInfo idFieldInfo;

    /**
     * 逻辑删除字段
     */
    private FieldInfo logicDeleteFieldInfo;

    /**
     * 租户id字段
     */
    private FieldInfo tenantIdFieldInfo;

    /**
     * 乐观锁字段
     */
    private FieldInfo versionFieldInfo;

    /**
     * onSet实体侦听器
     */
    private List<SetListener> onSetListeners;

    /**
     * entityDef引用的BeanInfo
     */
    private BeanInfo entityDefBeanInfo;

    /**
     * 是否可填充
     */
    private boolean fillable;

    public void setIdColumnInfo(FieldInfo idFieldInfo) {
        this.idFieldInfo = idFieldInfo;
    }

    public void setModule(Class<?> module){
        this.module = module;
    }

    public void setVersionColumnInfo(FieldInfo version) {
        this.versionFieldInfo = version;
    }

    public void setLogicDeleteColumnInfo(FieldInfo logicDeleteFieldInfo) {
        this.logicDeleteFieldInfo = logicDeleteFieldInfo;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public void setSchemaName(String schemaName) {
        this.schemaName = schemaName;
    }

    public void setSimpleColumnMap(Map<String, FieldInfo> simpleTypeFieldMap) {
        this.simpleColumnMap = simpleTypeFieldMap;
    }

    public void setUpdateColumn(List<FieldInfo> columns){
        this.updateColumns = columns.toArray(new FieldInfo[0]);
    }

    public void setQueryColumn(List<FieldInfo> columns) {
        this.queryColumns = columns.toArray(new FieldInfo[0]);
    }

    @Override
    public FieldInfo[] getQueryColumn() {
        return this.queryColumns;
    }

    public void setRelationFieldInfoList(List<RelationFieldInfo> relationFieldInfoList) {
        this.relationFieldInfoList = relationFieldInfoList;
    }

    public FieldInfo getIdColumnInfo() {
        return idFieldInfo;
    }

    public FieldInfo[] getUpdateColumn(){return this.updateColumns;}

    @Override
    public FieldInfo getLogicDeleteColumn() {
        return logicDeleteFieldInfo;
    }

    public String getTableName() {
        if (!this.isTableEntity()) {
            if (this.entityDefBeanInfo != null) {
                return this.entityDefBeanInfo.getTableName();
            }
        }
        return this.tableName;
    }

    public String getSchemaName() {
        return schemaName;
    }

    public Class<?> getModule() {
        return module;
    }

    @Override
    public boolean isTableEntity() {
        return StringUtil.isNoNull(this.tableName);
    }

    @Override
    public BeanInfo getEntityDefBeanInfo() {
        return this.entityDefBeanInfo;
    }

    public void setEntityDefBeanInfo(BeanInfo entityDefBeanInfo) {
        this.entityDefBeanInfo = entityDefBeanInfo;
    }

    @Override
    public FieldInfo getTenantIdColumn() {
        return tenantIdFieldInfo;
    }

    public void setTenantIdColumn(FieldInfo fieldInfo) {
        tenantIdFieldInfo = fieldInfo;
    }

    public FieldInfo getVersionColumnInfo() {
        return versionFieldInfo;
    }

    public void setOnSetListeners(List<SetListener> onSetListeners) {
        this.onSetListeners = onSetListeners;
    }

    public List<SetListener> getOnSetListeners() {
        return onSetListeners;
    }

    public Map<String, FieldInfo> getSimpleColumnMap() {
        return simpleColumnMap;
    }

    public List<RelationFieldInfo> getRelationFieldInfoList() {
        return relationFieldInfoList;
    }

    public void setFieldMap(Map<String, FieldInfo> fieldMap) {
        this.fieldMap = fieldMap;
    }

    public Map<String, FieldInfo> getFieldMap() {
        return fieldMap;
    }

    public void setFillable(boolean fillable) {
        this.fillable = fillable;
    }

    @Override
    public boolean isFillable() {
        return this.fillable;
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof BeanInfo)) {
            return false;
        }
        BeanInfo beanInfo = (BeanInfo) obj;
        return beanInfo == this || beanInfo.getModule().equals(this.module);
    }
}
